﻿using UnityEngine;
using System.Collections;

public class BundleLoader : Loader
{
    AssetBundleCreateRequest m_abRequest;
    WWW m_wwwRequest;
    CompressRequest m_unpackRequest;
    bool m_needUnpack;
    int m_stateCurrent;
    int m_stageCount = 1;

    public BundleLoader()
        : base(Loader.LoaderType.BUNDLE)
    {

    }

    protected override void Reset()
    {
        base.Reset();

        m_stateCurrent = 0;
        m_stageCount = 1;

        m_abRequest = null;

        if (m_wwwRequest != null)
        {
            m_wwwRequest.Dispose();
            m_wwwRequest = null;
        }
    }

    public override void Load()
    {
        base.Load();
        m_needUnpack = Config.DATA_COMPRESS && m_path.Contains(Config.STREAMING_ASSETS_PATH);
        if (m_async)
        {
            bool useWWW = false;
#if UNITY_ANDROID && !UNITY_EDITOR
			useWWW = !Config.Instance.ResourceSplit && m_path.Contains (Config.STREAMING_ASSETS_PATH);
#endif
            if (useWWW)
            {
                if (m_needUnpack)
                {
                    m_stageCount = 3;
                }
                string path = FileHelper.GetFullPath(m_path);
                m_wwwRequest = new WWW(path);
            }
            else
            {
                // 异步使用AssetBundle.LoadFromFileAsync,速度最快
                if (m_needUnpack)
                {
                    m_stageCount = 2;
                    byte[] bytes = FileHelper.ReadBytesFromFile(m_path);
                    m_unpackRequest = CompressRequest.CreateDecompress(bytes);

                }
                else
                {
                    string path = FileHelper.GetBundlePath(m_path);
                    m_abRequest = AssetBundle.LoadFromFileAsync(path);
                }
            }
        }
        else
        {
            AssetBundle ab = null;
            try
            {
                // 同步使用AssetBundle.LoadFromFile加载,速度最快
                if (m_needUnpack)
                {
                    byte[] temp = FileHelper.ReadBytesFromFile(m_path);
                    temp = Unpack(temp);
                    ab = AssetBundle.LoadFromMemory(temp);
                    //SaveBytesToFileRequest.CreateSaveBytesToFile(temp, m_path.Replace(Config.STREAMING_ASSETS_PATH, Config.UNPACK_DATA_PATH));
                    //SaveBytesToFileManager.Instance.CreateSaveBytesToFileReq(temp, m_path.Replace(Config.STREAMING_ASSETS_PATH, Config.UNPACK_DATA_PATH));
                }
                else
                {
                    string path = FileHelper.GetBundlePath(m_path);
                    ab = AssetBundle.LoadFromFile(path);
                }
            }
            catch (System.Exception e)
            {
                Debuger.LogError(e.Message);
            }
            finally
            {
                OnLoaded(ab);
            }
        }
    }

    byte[] Unpack(byte[] bytes)
    {
        byte[] result = new byte[1];
        int size = LzmaHelper.Uncompress(bytes, ref result);
        if (size == 0)
        {
            return null;
        }
        return result;
    }

    public override void Update(float dt)
    {
        if (m_state == LoaderState.LOADING)
        {
            if (m_abRequest != null)
            {
                if (m_abRequest.isDone)
                {
                    ++m_stateCurrent;
                    OnLoaded(m_abRequest.assetBundle);
                }
                else
                {
                    DoProgress(m_abRequest.progress);
                }
            }
            else if (m_unpackRequest != null)
            {
                if (m_unpackRequest.isDone)
                {
                    ++m_stateCurrent;
                    m_abRequest = AssetBundle.LoadFromMemoryAsync(m_unpackRequest.bytes);
                    //SaveBytesToFileRequest.CreateSaveBytesToFile(m_unpackRequest.bytes, m_path.Replace(Config.STREAMING_ASSETS_PATH, Config.UNPACK_DATA_PATH));
                    //SaveBytesToFileManager.Instance.CreateSaveBytesToFileReq(m_unpackRequest.bytes, m_path.Replace(Config.STREAMING_ASSETS_PATH, Config.UNPACK_DATA_PATH));
                    m_unpackRequest.Dispose();
                    m_unpackRequest = null;
                }
                else
                {
                    DoProgress(m_unpackRequest.progress);
                }
            }
            else
            {
                if (m_wwwRequest != null)
                {
                    if (m_wwwRequest.isDone)
                    {
                        ++m_stateCurrent;
                        if (!string.IsNullOrEmpty(m_wwwRequest.error))
                        {
                            Debuger.LogError(m_wwwRequest.error);
                            OnLoaded(null);
                        }
                        else
                        {
                            if (m_needUnpack)
                            {
                                m_unpackRequest = CompressRequest.CreateDecompress(m_wwwRequest.bytes);
                                m_wwwRequest.Dispose();
                                m_wwwRequest = null;
                            }
                            else
                            {
                                OnLoaded(m_wwwRequest.assetBundle);
                            }
                        }
                    }
                    else
                    {
                        DoProgress(m_wwwRequest.progress);
                    }
                }
            }
        }
    }

    void DoProgress(float rate)
    {
        OnLoadProgress((m_stateCurrent + rate) / m_stageCount);
    }

    void OnLoaded(AssetBundle ab)
    {
        // Debuger.Log ("Load {0} - {1} use {2}ms", m_path, m_async, m_watch.Elapsed.Milliseconds);

        OnLoadCompleted(ab);
    }
}